package com.lab303.powerproject.controller;

import com.lab303.powerproject.entity.PredictData;
import com.lab303.powerproject.entity.PredictElectricity;
import com.lab303.powerproject.service.PredictDataService;
import com.lab303.powerproject.util.ColdStrategy;
import com.lab303.powerproject.util.GenerateDemoData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
@RequestMapping("strategy")
public class StrategyController {

    @Autowired
    private PredictDataService predictDataService;

    @Autowired
    private ColdStrategy coldStrategy;
    private HashMap<String, String> eng2Chs = new HashMap<String, String>();
    private HashMap<String, String> testChs = new HashMap<String, String>();
    private HashMap<String, String> winGraph = new HashMap<String, String>();
    private HashMap<String, String> sumGraph = new HashMap<String, String>();

    void init() {
        testChs.put("dianliang", "电量");
        testChs.put("xuqiu", "需求计算");
        testChs.put("xinfeng", "新风");
        testChs.put("xuneng", "水蓄能");
        testChs.put("dimaiguan", "地埋管");
        testChs.put("zhujizhigong", "主机直供");
        testChs.put("zhujixuleng", "主机蓄冷");
        testChs.put("nuandian", "暖电");
        testChs.put("guangre", "光热");
    }

    void init1() { //夏季
        eng2Chs.clear();
        eng2Chs.put("dimaiguan", "免费冷直供地板");//免费冷供冷量
        eng2Chs.put("xinfeng", "免费冷直供新风");//新风机组直膨冷量
        eng2Chs.put("xuneng", "水蓄能罐放冷至地板");//水蓄能放冷量,
        eng2Chs.put("w2xinfeng", "水蓄能罐放冷至新风");
        eng2Chs.put("zhujizhigong", "主机直供地板");//主机直供地板
        eng2Chs.put("zhujixuleng", "主机蓄冷至水蓄能罐");//主机蓄冷量
        eng2Chs.put("guangre", "太阳能蓄热到暖电");
        eng2Chs.put("addix", "暖电放热至生活热水换热器");
    }

    void init2() {//冬季
        eng2Chs.clear();
        eng2Chs.put("xuneng", "水蓄能罐放热至地板");//水蓄能放冷量,
        eng2Chs.put("zhujizhigong", "主机直供地板");//主机直供地板
        eng2Chs.put("zhujixuleng", "主机蓄热至水蓄能罐");//主机蓄冷量
        eng2Chs.put("guangre", "太阳能直供地板");
        eng2Chs.put("addix", "主机蓄热至生活热水换热器");
    }

    void getSumGraphPath(){
        sumGraph.put("guangre","3#7,7#8");
        sumGraph.put("xuneng","1#6");
        sumGraph.put("dimaiguan","9#6");
        sumGraph.put("xinfeng","0#2,9#2");
        sumGraph.put("addix","3#7,7#8");
        sumGraph.put("zhujixuleng","4#5,5#1");
        sumGraph.put("w2xinfeng","1#2,0#2");
        sumGraph.put("zhujizhigong","4#5,5#2,5#6");
        sumGraph.put("addix","3#7,7#8");
    }

    void getWinGraphPath(){
        winGraph.put("xuneng","2#7");
        winGraph.put("guangre","1#7");
        winGraph.put("addix","3#9");
        winGraph.put("zhujizhigong","3#7");
        winGraph.put("zhujixuleng","4#3,3#2");
    }

    float convert(float num){
        return (float)(Math.round(num*10))/10;
    }

    //用于处理过渡季节
    Map<String, Object>  getCross(float tem1, float tem2, float hum1, float hum2, int flag, int person){

        Map<String, float[]> speData = getSpecificData(Float.valueOf(tem1), Float.valueOf(tem2), Float.valueOf(hum1), Float.valueOf(hum2), flag, person);
        String appendDLPoint[]  = {"bangong","zhaoming","xiaofang","other"};

        float dls[] = speData.get("dianliang");
        for(int i = 0;i<4;++i){
            float single[] = speData.get(appendDLPoint[i]);
            for(int j = 0;j<24;++j){
                dls[j] += single[j];
                dls[j] = convert(dls[j]);
            }
        }

        String crossAns = "3#7,7#8";//表示返回的图谱路径
        String NodeAns = "3,7,8";//
        String retPath = "(23:00~6:00)        暖电放热至生活热水换热器,(7:00~17:00)        太阳能蓄热到暖电";
        Map res = new HashMap<String, Object>();
        float nls[] = new float[24];//为每个小时预测的能量值

        res.put("nls", nls);
        res.put("dls", speData.get("dianliang"));
        res.put("path", crossAns.split(","));
        res.put("node", NodeAns.split(","));
        res.put("gongkuang", retPath.toString().split(","));
        return res;
    }

    Map<String, float[]> getSpecificData(float tem1, float tem2, float hum1, float hum2, int flag, int person) {
        return GenerateDemoData.doGenerate(tem1, tem2, hum1, hum2, flag, person); //flag 1_夏季 2_冬季
    }

    public Map<String, Object> getWinter(String tem1, String tem2, int flag, int person) {
        init2();
        getWinGraphPath();
        Map<String, float[]> speData = getSpecificData(Float.valueOf(tem1), Float.valueOf(tem2), 10, 30, flag, person);

        String appendDLPoint[]  = {"bangong","zhaoming","xiaofang","other"};
        String appendNLPoint[]  = {"meetingData","restaurantData"};

        float dls[] = speData.get("dianliang");
        for(int i = 0;i<4;++i){
            float single[] = speData.get(appendDLPoint[i]);
            for(int j = 0;j<24;++j){
                dls[j] += single[j];
                dls[j] = convert(dls[j]);
            }
        }

        float nls[] = speData.get("xuqiu");
        for(int i = 0;i<2;++i){
            float single[] = speData.get(appendNLPoint[i]);
            for(int j = 0;j<24;++j){
                nls[j] += single[j];
                nls[j] = convert(nls[j]);
            }
        }


        Iterator<String> iter = speData.keySet().iterator();
        while (iter.hasNext()) {
            String str = iter.next();
            if (str.equals("temperature") || str.equals("humidity")||str.equals("bangong") || str.equals("zhaoming")||str.equals("xiaofang") || str.equals("other")||str.equals("meetingData") || str.equals("restaurantData")) {
                iter.remove();
            }
        }
        for (Map.Entry<String, float[]> i : speData.entrySet()) {

            System.out.print("Key:" + testChs.get(i.getKey()) + "    ");
            for (int j = 0; j < i.getValue().length; ++j) {
                System.out.print(" " + i.getValue()[j]);
            }
            System.out.println();
        }
        Map<String, ArrayList<Integer>> condition = new HashMap<String, ArrayList<Integer>>();
        HashMap<String, String> str2Hour = new HashMap<String, String>();

        Map res = new HashMap<String, Object>();

        Object[] keys = speData.keySet().toArray();
        for (int i = 0; i < 24; ++i) {
            float xuneng = 0, zhujizhigong = 0, zhujixuleng = 0, guangre = 0;//为与夏天保持一致，这里叫主机蓄冷
            //xuneng 水蓄能放热量,  主机直供热量 diyuanrebeng ,guangre 太阳能直供热量;
            for (int j = 0; j < keys.length; ++j) {
                String name = keys[j].toString();
                float nl = speData.get(name)[i];
                if (nl != 0) {
                    if (condition.get(name) == null) {
                        condition.put(name, new ArrayList<Integer>());
                    }
                    if (name == "zhujizhigong") {
                        if (i >= 11 && i <= 18) condition.get(name).add(i);//11:00~18:00如果供能不为0，说明开启了主机功能策略;
                    } else {
                        condition.get(name).add(i);
                    }
                }
            }
        }

        Object[] ckeys = condition.keySet().toArray();
        for (int i = 0; i < ckeys.length; ++i) {
            String conName = ckeys[i].toString();
            if (conName == "dianliang" || conName == "xuqiu" || conName == "xinfeng" || conName == "nuandian") continue;
            ArrayList<Integer> conHour = condition.get(conName);
            if (conHour.size() == 0) continue;
            ArrayList<Integer> tmp = new ArrayList<>();
            for (int k = 0; k < conHour.size(); ++k) tmp.add(conHour.get(k));
            for (int j = 1; j < tmp.size() - 1; ++j) {
                if (tmp.get(j) == tmp.get(j - 1) + 1 && tmp.get(j) + 1 == tmp.get(j + 1)) {
                    conHour.set(j, -1);
                }
            }
        }

        for (int i = 0; i < ckeys.length; ++i) {
            StringBuilder temp = new StringBuilder();
            String cname = ckeys[i].toString();
            if (cname == "dianliang" || cname == "xuqiu"||cname == "zhujixuleng") continue;
            ArrayList<Integer> Hour = condition.get(cname);
            ArrayList<String> conHour = new ArrayList<>();
            for (int j = 0; j < Hour.size(); ++j) {
                if (Hour.get(j) != -1) {
                    conHour.add(Hour.get(j) + ":00");
                }
            }
            if (conHour.size() == 0){
                continue;
            }else{
                if(conHour.size() == 1){
                    conHour.add( String.valueOf((Integer.valueOf(conHour.get(0).split(":")[0]) + 1)%24) + ":00");
                }
            }
            int x = 0;
            while (x + 2 <= conHour.size()) {
                if (x != 0) temp.append("、");
                temp.append(conHour.get(x) + "~" + conHour.get(x + 1));
                x += 2;
            }
            if (x != conHour.size()) {
                if (conHour.size() > 2) {
                    temp.append("、" + conHour.get(x) + "~" + String.valueOf((Integer.valueOf(conHour.get(x).split(":")[0]) + 1)%24) + ":00");
                } else {
                    temp.append(conHour.get(x) + "~" + String.valueOf((Integer.valueOf(conHour.get(x).split(":")[0]) + 1)%24) + ":00");
                }
            }
            str2Hour.put(cname, temp.toString());
        }

        StringBuilder retPath = new StringBuilder();
        StringBuilder engPath = new StringBuilder();
        int f = 0;
        for (int j = 0; j < keys.length; ++j) {
            String name = keys[j].toString();
            if (name == "dianliang" || name == "xuqiu" || name == "xinfeng" || name == "dimaiguan"||name == "nuandian") continue;
            if (str2Hour.get(name) != null) {
                if (f != 0){
                    retPath.append(",");
                    engPath.append(",");
                }
                retPath.append("(" + str2Hour.get(name) + ")" + "        " + eng2Chs.get(name));
                engPath.append(name);
                f++;
            }
        }
        if(str2Hour.get("zhujizhigong") == null&&(Float.valueOf(tem1) +  Float.valueOf(tem2)<0||Float.valueOf(tem1)<-5)){
            retPath.append(",(17:00~18:00)" + "        " + eng2Chs.get("zhujizhigong"));
            engPath.append(",zhujizhigong");
        }// 自定义的补充

        retPath.append(",(23:00~6:00)" + "        " + eng2Chs.get("addix"));
        engPath.append(",addix");
        retPath.append(",(23:00~6:00)" + "        " + eng2Chs.get("zhujixuleng"));
        engPath.append(",zhujixuleng");

        StringBuilder  graphStr =  new StringBuilder();
        String []winGraphArr = engPath.toString().split(",");
        for(int i = 0;i<winGraphArr.length;++i){
            if(i != 0)graphStr.append(",");
            graphStr.append(winGraph.get(winGraphArr[i]));
        }
        Set<String> winPath = new HashSet<>();
        Set<String> winNode = new HashSet<>();
        String [] arr = graphStr.toString().split(",");
        for(int i =0;i<arr.length;++i)winPath.add(arr[i]);
        winPath.add("5#7");
        String winAns = "",NodeAns = "";

        for(int i = 0;i<winPath.toArray().length;++i){
            if(i !=0)winAns += ",";
            winAns += winPath.toArray()[i];
        }

        for(int i = 0;i<winAns.split(",|#").length;++i){
            winNode.add(winAns.split(",|#")[i]);
        }
        for(int i = 0;i<winNode.toArray().length;++i){
            if(i !=0)NodeAns += ",";
            NodeAns += winNode.toArray()[i];
        }

        System.out.println(winAns);
        System.out.println(NodeAns);

        System.out.println("图谱");
        System.out.println(engPath.toString());
        System.out.println();
        System.out.println("最终策略");
        System.out.println(retPath);
        System.out.println();
        res.put("nls", speData.get("xuqiu"));
        res.put("dls", speData.get("dianliang"));
        res.put("path", winAns.split(","));
        res.put("node", NodeAns.split(","));
        res.put("gongkuang", retPath.toString().split(","));
        return res;
    }


    @PostMapping("/getHourData")
    @ResponseBody
    public Map<String, Object> getHourData(String tem1, String tem2, String hum1, String hum2, int flag, int person) {
        init();
        getSumGraphPath();
        if (flag == 0) {
            return getWinter(tem1, tem2, flag, person);
        }else if(Float.valueOf(tem1) >=16&&Float.valueOf(tem2) <26){
            return getCross(Float.valueOf(tem1), Float.valueOf(tem2), Float.valueOf(hum1), Float.valueOf(hum2), flag, person);
        }
        init1();
        Map<String, float[]> speData = getSpecificData(Float.valueOf(tem1), Float.valueOf(tem2), Float.valueOf(hum1), Float.valueOf(hum2), flag, person);


        String appendDLPoint[]  = {"bangong","zhaoming","xiaofang","other"};
        String appendNLPoint[]  = {"meetingData","restaurantData"};

        float dls[] = speData.get("dianliang");
        for(int i = 0;i<4;++i){
            float single[] = speData.get(appendDLPoint[i]);
            for(int j = 0;j<24;++j){
                dls[j] += single[j];
                dls[j] = convert(dls[j]);
            }
        }

        float nls[] = speData.get("xuqiu");
        for(int i = 0;i<2;++i){
            float single[] = speData.get(appendNLPoint[i]);
            for(int j = 0;j<24;++j){
                nls[j] += single[j];
                nls[j] = convert(nls[j]);
            }
        }

        Iterator<String> iter = speData.keySet().iterator();
        while (iter.hasNext()) {
            String str = iter.next();
            if (str.equals("temperature") || str.equals("humidity")||str.equals("bangong") || str.equals("zhaoming")||str.equals("xiaofang") || str.equals("other")||str.equals("meetingData") || str.equals("restaurantData")) {
                iter.remove();
            }
        }
        for (Map.Entry<String, float[]> i : speData.entrySet()) {
            System.out.print("Key:" + testChs.get(i.getKey()) + " " + i.getKey() +  "    ");
            for (int j = 0; j < i.getValue().length; ++j) {
                System.out.print(" " + i.getValue()[j]);
            }
            System.out.println();
        }
        Map<String, ArrayList<Integer>> condition = new HashMap<String, ArrayList<Integer>>();
        HashMap<String, String> str2Hour = new HashMap<String, String>();

        Map res = new HashMap<String, Object>();

        Object[] keys = speData.keySet().toArray();
        for (int i = 0; i < 24; ++i) {
            float dimaiguan = 0, zhujizhigong = 0, zhujixuleng = 0, xuneng = 0, xinfeng = 0;
            //dimaiguan 免费冷供冷量,  主机蓄冷量 diyuanrebeng 主机直供冷量,xuneng 水蓄能放冷量,新风机组直膨冷量 xinfeng;
            for (int j = 0; j < keys.length; ++j) {
                String name = keys[j].toString();
                float nl = speData.get(name)[i];
                if (name == "dimaiguan") {
                    if (condition.get(name) == null) {
                        condition.put(name, new ArrayList<Integer>());
                    }
                    condition.get(name).add(i);
                } else if (name == "addix" && (i <= 6 || i == 23)) {
                    if (condition.get(name) == null) {
                        condition.put(name, new ArrayList<Integer>());
                    }
                    condition.get(name).add(i);
                } else {
                    if (nl != 0) {
                        if (condition.get(name) == null) {
                            condition.put(name, new ArrayList<Integer>());
                        }
                        if (name == "zhujizhigong") {
                            if (i >= 11 && i <= 18) condition.get(name).add(i);//11:00~18:00如果供能量不为0，说明开启了主机供能策略;
                        } else {
                            condition.get(name).add(i);
                        }
                    }
                }
            }
        }

        Object[] ckeys = condition.keySet().toArray();
        for (int i = 0; i < ckeys.length; ++i) {
            String conName = ckeys[i].toString();
            if (conName == "dianliang" || conName == "xuqiu") continue;
            ArrayList<Integer> conHour = condition.get(conName);
            if (conHour.size() == 0) continue;
            ArrayList<Integer> tmp = new ArrayList<>();
            for (int k = 0; k < conHour.size(); ++k) tmp.add(conHour.get(k));
            for (int j = 1; j < tmp.size() - 1; ++j) {
                if (tmp.get(j) == tmp.get(j - 1) + 1 && tmp.get(j) + 1 == tmp.get(j + 1)) {
                    conHour.set(j, -1);
                }
            }
        }

        for (int i = 0; i < ckeys.length; ++i) {
            StringBuilder temp = new StringBuilder();
            String cname = ckeys[i].toString();
            if (cname == "dianliang" || cname == "xuqiu"||cname == "zhujixuleng") continue;
            ArrayList<Integer> Hour = condition.get(cname);
            ArrayList<String> conHour = new ArrayList<>();
            for (int j = 0; j < Hour.size(); ++j) {
                if (Hour.get(j) != -1) {
                    conHour.add(Hour.get(j) + ":00");
                }
            }
            if (conHour.size() == 0){
                continue;
            }else{
                if(conHour.size() == 1){
                    conHour.add( String.valueOf((Integer.valueOf(conHour.get(0).split(":")[0]) + 1)%24) + ":00");
                }
            }
            int x = 0;
            while (x + 2 <= conHour.size()) {
                if (x != 0) temp.append("、");
                temp.append(conHour.get(x) + "~" + conHour.get(x + 1));
                x += 2;
            }
            if (x != conHour.size()) {
                if (conHour.size() > 2) {
                    temp.append("、" + conHour.get(x) + "~" + String.valueOf((Integer.valueOf(conHour.get(x).split(":")[0]) + 1)%24) + ":00");
                } else {
                    temp.append(conHour.get(x) + "~" + String.valueOf((Integer.valueOf(conHour.get(x).split(":")[0]) + 1)%24) + ":00");
                }
            }
            str2Hour.put(cname, temp.toString());
        }

        StringBuilder retPath = new StringBuilder();
        StringBuilder retEngPath = new StringBuilder();
        int f = 0;
        for (int j = 0; j < keys.length; ++j) {
            String name = keys[j].toString();
            if (name == "dianliang" || name == "xuqiu"||name == "nuandian") continue;
            if (str2Hour.get(name) != null) {
                if (f != 0) {
                    retPath.append(",");
                    retEngPath.append(",");
                }
                retPath.append("(" + str2Hour.get(name) + ")" + "        " + eng2Chs.get(name));
                retEngPath.append(name);
                f++;
            }
        }
        if ((Float.valueOf(tem1) + Float.valueOf(tem2)) / 2 > 26 && (Float.valueOf(hum1) + Float.valueOf(hum2)) / 2 > 40) {
            retPath.append(",(" + str2Hour.get("xinfeng") + ")" + "        " + eng2Chs.get("w2xinfeng"));
            retEngPath.append(",w2xinfeng");
        }
        retPath.append(",(23:00~6:00)" + "        " + eng2Chs.get("addix"));
        retEngPath.append(",addix");
        retPath.append(",(23:00~6:00)" + "        " + eng2Chs.get("zhujixuleng"));
        retEngPath.append(",zhujixuleng");
        System.out.println("图谱");
        StringBuilder  graphStr =  new StringBuilder();
        String []sumGraphArr = retEngPath.toString().split(",");
        for(int i = 0;i<sumGraphArr.length;++i){
            if(i != 0)graphStr.append(",");
            graphStr.append(sumGraph.get(sumGraphArr[i]));
        }

        Set<String> sumPath = new HashSet<>();
        Set<String> sumNode = new HashSet<>();
        String [] arr = graphStr.toString().split(",");
        for(int i =0;i<arr.length;++i)sumPath.add(arr[i]);
        sumPath.add("0#4");
        sumPath.add("10#4");
        sumPath.add("10#6");
        String sumAns = "",NodeAns = "";
        for(int i = 0;i<sumPath.toArray().length;++i){
            if(i !=0)sumAns += ",";
            sumAns += sumPath.toArray()[i];
        }
        for(int i = 0;i<sumAns.split(",|#").length;++i){
            sumNode.add(sumAns.split(",|#")[i]);
        }
        for(int i = 0;i<sumNode.toArray().length;++i){
            if(i !=0)NodeAns += ",";
            NodeAns += sumNode.toArray()[i];
        }


        System.out.println(sumAns);
        System.out.println(NodeAns);
        System.out.println("最终策略");
        System.out.println(retPath);
        System.out.println(retEngPath);
        System.out.println();

        res.put("nls", speData.get("xuqiu"));
        res.put("dls", speData.get("dianliang"));
        res.put("path", sumAns.split(","));
        res.put("node", NodeAns.split(","));
        res.put("gongkuang", retPath.toString().split(","));
        return res;
    }

    @RequestMapping("/predict_data")
    @ResponseBody
    public Map getPredictData(){
        String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        float[] powerArray = predictDataService.getPredictElectricityDataByDayAndId(format, 36);
        float[] electricityArray = predictDataService.getPredictDlByDayAndId(format,1);
        Map map = new HashMap();
        map.put("power",powerArray);
        map.put("electricity",electricityArray);
        return map;
    }

    public static void main(String[] args) {
        StrategyController sc = new StrategyController();
        sc.getHourData("30", "35", "80", "100", 1, 400);
    }
}